﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using Microsoft.Mtool.FSM;
using System.Xml;
using System.Xml.Serialization;

namespace MToolStudio.Render
{
    [Serializable]
    public class StateR : IRenderable
    {
        private const int ActionIconInitialRadius = 20;
        private const int DefaultStatePenWidth = 3;
        private const int FocusStatePenWidth = 5;
        private readonly static Color DefaultPaintStringColor = Color.Green;
        private const int DefaultPaintFontHeight = 8;
        private readonly static Font DefaultPaintStringFont = new Font("Arial", DefaultPaintFontHeight);
        private readonly static Color DefaultStateForeColor = Color.BlueViolet;
        private Point position;
        private double radius = ActionIconInitialRadius;
        private State state;
        private int selfCurveCount;

        private string _state_id;

        public StateR()//parameterless ctor for the xml serializer
        { }

        public StateR(State state)
        {
            this.state = state;
            radius = ActionIconInitialRadius;
            position.X = position.Y = -10000;
        }

        public void PostSerializationInit(FSM machine)
        {
            state = machine.GetState(_state_id);
        }

        [XmlAttribute]
        public int SelfCurveCount
        {
            get { return selfCurveCount; }
            set { selfCurveCount = value; }
        }

        //used only for serialzation
        [XmlAttribute]
        public string InnerStateId
        {
            get { return InnerState.Id; }
            set { _state_id = value; }
        }

        [XmlIgnore]
        public State InnerState
        {
            get { return state; }
            set { state = value; }
        }

        [XmlElement]
        public Point Position
        {
            get { return position; }
            set { position = value; }
        }

        [XmlAttribute]
        public double Radius
        {
            get { return radius; }
            set { radius = value; }
        }

        public double Scale
        {
            get { return radius / ActionIconInitialRadius; }
            set { radius = Scale * ActionIconInitialRadius; }
        }

        public void Paint(Graphics g)
        {
            using (Pen pp = new Pen(DefaultStateForeColor, DefaultStatePenWidth))
            {
                g.DrawEllipse(pp, (float)(Position.X - radius),
                    (float)(Position.Y - radius), (float)radius * 2, (float)radius * 2);
            }
            //g.FillPie(
        }

        public void PaintFocus(Graphics g)
        {
            using (Pen pp = new Pen(DefaultStateForeColor, FocusStatePenWidth))
            {
                g.DrawEllipse(pp, (float)(Position.X - radius),
                    (float)(Position.Y - radius), (float)radius * 2, (float)radius * 2);
            }
            //g.FillPie(
        }

        public void PrePaint(Graphics g)
        { }

        public void PostPaint(Graphics g)
        {
            using (Brush bb = new SolidBrush(state.Type == StateType.Entry ? Color.Wheat : Color.White))
            {
                g.FillEllipse(bb, (float)(Position.X - radius + DefaultStatePenWidth / 2),
                    (float)(Position.Y - radius + DefaultStatePenWidth / 2),
                    (float)(radius - DefaultStatePenWidth / 2) * 2,
                    (float)(radius - DefaultStatePenWidth / 2) * 2);
            }
            using (Brush bb = new SolidBrush(DefaultPaintStringColor))
            {
                g.DrawString(InnerState.Id, DefaultPaintStringFont, bb, new PointF((float)(Position.X - radius),
                    (float)(Position.Y - DefaultPaintFontHeight / 2)));
            }
        }

        public void PaintToured(Graphics g)
        {
            double touRadius = RenderConstants.TouredStateRadiusRatio * radius;
            using (Brush bb = new SolidBrush(RenderConstants.TouredStateColor))
            {
                g.FillEllipse(bb, (float)(Position.X - touRadius + DefaultStatePenWidth / 2),
                    (float)(Position.Y - touRadius + DefaultStatePenWidth / 2),
                    (float)(touRadius - DefaultStatePenWidth / 2) * 2,
                    (float)(touRadius - DefaultStatePenWidth / 2) * 2);
            }
        }

        public bool IsSelected(Point p)
        {
            return UIUtility.DistanceSqrBetween(p, Position) < radius * radius;
        }
    } 
}
